import requests
from bs4 import BeautifulSoup
from datetime import datetime
from typing import List, Dict, Optional
import logging
from utils.validators import DataValidator

class CrawlerService:
    """爬虫服务类"""
    
    def __init__(self, config=None):
        if config is None:
            from config.settings import get_config
            config = get_config()
        
        self.base_url = config.CRAWLER_BASE_URL
        self.headers = {
            'User-Agent': config.CRAWLER_USER_AGENT
        }
        self.timeout = config.CRAWLER_TIMEOUT
        self.max_pages = config.CRAWLER_MAX_PAGES
        self.target_count = config.CRAWLER_TARGET_COUNT
    
    def crawl_lottery_data(self, max_pages: int = 3, target_count: int = 30) -> dict:
        """爬取双色球数据"""
        try:
            all_data = []
            page = 1
            
            while page <= max_pages and len(all_data) < target_count:
                try:
                    response = requests.get(
                        f"{self.base_url}&pageNo={page}",
                        headers=self.headers,
                        timeout=self.timeout
                    )
                    response.raise_for_status()
                    
                    soup = BeautifulSoup(response.content, 'html.parser')
                    rows = soup.find_all('tr')[1:]  # 跳过表头
                    
                    for row in rows:
                        if len(all_data) >= target_count:
                            break
                        
                        cells = row.find_all('td')
                        if len(cells) < 4:
                            continue
                        
                        try:
                            # 解析期数和日期
                            draw_info = cells[0].get_text(strip=True)
                            draw_date_str = cells[1].get_text(strip=True)
                            
                            # 解析开奖号码
                            numbers_text = cells[2].get_text(strip=True)
                            numbers = [int(num) for num in numbers_text.split() if num.isdigit()]
                            
                            if len(numbers) != 7:
                                continue
                            
                            red_balls = numbers[:6]
                            blue_ball = numbers[6]
                            
                            # 验证数据有效性
                            if not DataValidator.validate_ball_numbers(red_balls, blue_ball):
                                continue
                            
                            # 解析日期
                            draw_date = datetime.strptime(draw_date_str, '%Y-%m-%d').date()
                            
                            # 获取奖金信息
                            prize_info = cells[3].get_text(strip=True) if len(cells) > 3 else ''
                            
                            lottery_data = {
                                'draw_date': draw_date,
                                'draw_number': draw_info,
                                'red_balls': red_balls,
                                'blue_ball': blue_ball,
                                'prize_info': prize_info
                            }
                            
                            all_data.append(lottery_data)
                            
                        except Exception as e:
                            logging.warning(f"解析行数据失败: {str(e)}")
                            continue
                    
                    page += 1
                    
                except Exception as e:
                    logging.error(f"爬取第{page}页失败: {str(e)}")
                    break
            
            return {
                'success': True,
                'data': all_data,
                'total_crawled': len(all_data),
                'pages_crawled': page - 1
            }
            
        except Exception as e:
            logging.error(f"爬取数据失败: {str(e)}")
            return {
                'success': False,
                'error': str(e),
                'data': [],
                'total_crawled': 0,
                'pages_crawled': 0
            }
    
    def get_latest_draw_info(self) -> Optional[Dict]:
        """获取最新开奖信息"""
        try:
            result = self.crawl_lottery_data(max_pages=1, target_count=1)
            if result['success'] and result['data']:
                return result['data'][0]
            return None
        except Exception as e:
            logging.error(f"获取最新开奖信息失败: {str(e)}")
            return None
    
    def validate_lottery_data(self, data: dict) -> bool:
        """验证开奖数据有效性"""
        try:
            required_fields = ['draw_date', 'draw_number', 'red_balls', 'blue_ball']
            for field in required_fields:
                if field not in data:
                    return False
            
            if not DataValidator.validate_draw_number(data['draw_number']):
                return False
            
            if not DataValidator.validate_ball_numbers(data['red_balls'], data['blue_ball']):
                return False
            
            return True
        except Exception:
            return False
